[情境任務]
小當家:我把餐廳大致上的料理都開發出來囉!名單都整理好了,直接列上去就行
解師傅:太好了~哇!這菜色有點多呢!一個一個列好像太花時間了…不知道能不能一次把這些通通放到菜單上呢?老闆你有什麼想法嗎?
用複製組件的方法雖然不是不行,但我們想要更有效率且好維護的方法
當資料開始多時,將每個元件都複製、塞 props,這並不是一個好維護的作法,
明明是做同一件事卻看起來很冗長
<ul>
<List name="蘆筍沙拉" price={100} />
<List name="辣炒空心菜" price={120} />
<List name="雞蛋豆腐" price={150}/>
<List name="鳳梨蝦球" price={300}/>
<List name="糖醋雞丁" price={200}/>
<List name="砂鍋魚頭" price={500}/>
<List name="竹筍炒肉絲" price={150}/>
<List name="梨山高麗菜" price={120}/>
</ul>
這結構其實都一樣,我們可以將資料模組化,再從一個集合中把資料渲染到畫面,像 Vue、Angular 會有自定義渲染列表的模版,而 React 並沒有列表模版,大多是使用 JavaScript 本身的語法 map
產生,以下列出陣列與物件的渲染方式
function App() {
const chef = [
{ name: "小當家" },
{ name: "解師傅" },
{ name: "雷恩" }
];
return (
<ul>
{chef.map((item, index) => (
<li key={item.name}>
{index + 1}. {item.name}
</li>
))}
</ul>
);
}
export default App;
資料為一個陣列,要重複渲染的地方用大括弧 {} 包住,使用 JavaScript 的陣列語法 map
將每個 item
渲染出來,map
的第二個參數為索引值 index
除了陣列,物件也可以渲染
function App() {
const chef = {
name: "小當家",
age: 13,
height: 150
};
return (
<ul>
{Object.keys(chef).map((key) => {
const value = chef[key];
return (
<li key={value}>
{key}: {value}
</li>
);
})}
</ul>
);
}
export default App;
物件使用 Object.keys
先把物件屬性變成陣列,再使用 map
渲染
物件渲染出來的結果順序不一定相同,如果要照資料排序須將資料改為陣列
你可能會發現,不管是陣列或物件,為什麼渲染列表第一個元素都有 key
屬性?
不管是陣列或物件,渲染出來的第一個元素需要帶入 key
屬性,key
是用來辨別元素的改變或增減
如陣列改變,React 會透過 key
去比較新舊元素有無變更,只改變有變更的元素,才不會整個列表再被重新渲染,影響效能
如果你忘了加 key
,在 console 也會跳出錯誤,提醒你要加 key
◆ 不建議使用索引作為 key
,尤其如果項目的順序會改變的話,這會對效能產生不好的影響,也可能會讓 component 資料產生問題,最好的方法還是加上唯一值,通常可以加上 id
[任務解題]
利用陣列渲染出 menu,渲染 component,並帶入 item 的 props,記得也要加上 key 哦!
import List from "./components/List";
function App() {
const menu = [
{ name: "蘆筍沙拉", price: 100 },
{ name: "辣炒空心菜", price: 120 },
{ name: "雞蛋豆腐", price: 150 },
{ name: "鳳梨蝦球", price: 300 },
{ name: "糖醋雞丁", price: 200 },
{ name: "砂鍋魚頭", price: 500 },
{ name: "竹筍炒肉絲", price: 150 },
{ name: "梨山高麗菜", price: 120 },
{ name: "五更腸旺", price: 250 },
{ name: "客家小炒", price: 250 },
{ name: "三杯杏鮑菇", price: 180 }
];
return (
<div className="App">
<h1>React 熱炒店</h1>
<ul>
{menu.map((item, index) => (
<List
key={item.name}
name={item.name}
price={item.price}
index={index}
></List>
))}
</ul>
</div>
);
}
export default App;
餐廳的菜單列表就這樣被渲染出來囉!
有新的菜色或需要調整時,直接更改 menu 陣列就可以了!
學會渲染列表就可以做很多事了,看起來簡短很多,重要的是好維護,當需要修改資料時,不用去找 component 的 props,直接統一在資料模組管理就好了!
本文將同步更新至我的部落格
Lala 的前端大補帖